package game

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"navi-mumbai/common/gensql"
)

var _ GameProviderModel = (*customGameProviderModel)(nil)

type (
	// GameProviderModel is an interface to be customized, add more methods here,
	// and implement the added methods in customGameProviderModel.
	GameProviderModel interface {
		gameProviderModel
		Find(ctx context.Context, state, pageNo, pageSize int64) ([]*GameProvider, error)
		Count(ctx context.Context, state int64) (int64, error)
		UpdateProvider(ctx context.Context, update *UpdateProvider) error
	}

	customGameProviderModel struct {
		*defaultGameProviderModel
		genSql *gensql.GenSql
	}
)

// NewGameProviderModel returns a model for the database table.
func NewGameProviderModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) GameProviderModel {
	return &customGameProviderModel{
		defaultGameProviderModel: newGameProviderModel(conn, c, opts...),
		genSql:                   gensql.NewGenSql(),
	}
}

func (m *customGameProviderModel) Find(ctx context.Context, state, pageNo, pageSize int64) ([]*GameProvider, error) {
	// 分页
	if pageNo < 1 {
		pageNo = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}

	q := fmt.Sprintf("select %s from %s ", gameProviderRows, m.table)
	m.genSql.InitSql(q)
	if state != 0 {
		m.genSql = m.genSql.Where("state = ?", state)
	}

	query, values, err := m.genSql.OrderBy("create_time ASC").Limit(uint64(pageSize)).Offset(uint64((pageNo - 1) * pageSize)).ToSql()
	if err != nil {
		return nil, err
	}

	resp := make([]*GameProvider, 0)
	err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
	switch err {
	case nil:
		return resp, nil
	default:
		return nil, err
	}
}

func (m *customGameProviderModel) Count(ctx context.Context, state int64) (int64, error) {
	q := fmt.Sprintf("select count(provider_id) from %s ", m.table)
	m.genSql.InitSql(q)

	if state != 0 {
		m.genSql = m.genSql.Where("state = ?", state)
	}

	query, values, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}

	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

type UpdateProvider struct {
	ProviderId   int64  // 游戏供应商id
	ProviderName string // 游戏供应商名称
	Logo         string // 游戏供应商logo
	State        int64
}

func (m *customGameProviderModel) UpdateProvider(ctx context.Context, update *UpdateProvider) error {
	mumbaiGameGameProviderProviderIdKey := fmt.Sprintf("%s%v", cacheMumbaiGameGameProviderProviderIdPrefix, update.ProviderId)

	q := fmt.Sprintf("update %s ", m.table)
	m.genSql.InitSql(q)
	if update.ProviderName != "" {
		m.genSql = m.genSql.Set("provider_name", update.ProviderName)
	}
	if update.Logo != "" {
		m.genSql = m.genSql.Set("logo", update.Logo)
	}
	if update.State != 0 {
		m.genSql = m.genSql.Set("state", update.State)
	}
	q, v, err := m.genSql.Where("provider_id = ?", update.ProviderId).ToSql()
	if err != nil {
		return err
	}

	_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		return conn.ExecCtx(ctx, q, v...)
	}, mumbaiGameGameProviderProviderIdKey)
	return err
}
